<?php
// $Id: permissions_controller.php @2009 ccbox.net 1:22 2009-5-14 $

/**
 * Controller_Admin_Default controller
 *  permission_id namespace controller action aliasname rbac
 */
class Controller_Admin_Permissions extends Controller_Admin_Abstract
{
    /* ******************************************************************** */
    function actionIndex()
    {
        $show_box['title'] = '权限管理首页';
        //echo 'Admin_Permissions index';
    }
    
    /* ******************************************************************** */
    function actionList()
    {
        $show_box['title'] = '权限列表';
        // 分页查询
        $page = intval($this->_context->page);
        if ($page < 1) $page = 1;
        // 构建查询条件
        $list_namespace  = $this->_context->list_namespace;
        $list_controller = $this->_context->list_controller;
        $condition = $url_args = array();
        if ( !empty($list_namespace)){
            $condition['namespace'] = $list_namespace;
            $url_args['list_namespace'] = $list_namespace;
        }else{
                $url_args['list_namespace'] = '';
        }
        if ( !empty($list_controller)){
            $condition['controller'] = $list_controller;
            $url_args['list_controller'] = $list_controller;
        }
        $this->_view['url_args'] = $url_args;
        // 构造查询对象
        $select = Admin_Permissions::find($condition);
        $select -> limitPage($page, 15);

        // 将分页信息和查询到的数据传递到视图
        $this->_view['pagination']  = $select->getPagination();
        $this->_view['permissions'] = $select->getAll();

        // 构建二级联动下拉框
        $NamespaceControllerArr = Helper_Permissions::getNamespaceControllerArrs();
        $this->_view['ncArr'] = $NamespaceControllerArr;

    }

    /* ******************************************************************** */
    function actionUpdate()
    {
        $show_box['title'] = '更新权限内容';
        if ($this->_context->isPOST() )
        {
            // changeProps() 方法可以批量修改 task 对象的属性，但不会修改只读属性的值
            foreach ($this->_context->rbac as $key=>$value) {
                $post = Admin_Permissions::find('permission_id = ?', $key)->query();
                $post -> rbac = $value;
                $post -> aliasname = $_POST['aliasname'][$key];
                $post -> save();
            }
        }
            return $this->_redirect(url('admin::Permissions/list'));
    }

    /* ******************************************************************** */
    //根据文件内容找出相应的命名空间，控制器，动作，权限描述，从而更新权限列表
    function actionRefreshtable()
    {
        $show_box['title'] = '更新权限列表';
        $this->md_perManager = new Helper_Permissions;
        $refresh_permission = $this->md_perManager->updatePermissions(Q::ini('app_config/APP_DIR') . '/controller/');
        if ($refresh_permission){
            return $this->_redirectMessage(
                '更新成功', 
                '权限列表更新成功。',
                url('admin::permissions/list'));
        }else{
            return $this->_redirectMessage(
                '更新失败', 
                '权限列表更新失败。',
                url('admin::permissions/index'));
        }
    }
/*****************************更新权限文件测试******************************************/
	function actionTest()
	{
		$nca = Admin_Permissions::find()->getAll();
		//print_r($nca->toArray());
		/*$nca_arrs = $nca->toArray();
		foreach($nca_arrs as $nca_arr):
			print_r($nca_arr);
			echo "<br/>";
			echo "<br/>";
		endforeach;
		*/
		/*foreach($nca as $object):
			//print_r($object);
			echo "<br/>";
			echo "<br/>";
			echo "<br/>";echo "<br/>";echo "<br/>";
			//print_r($object);
			//print_r($object->roles);
			//echo "<br/>";echo "<br/>";echo "<br/>";
			//print_r($object->users);
		endforeach;
		*/
	/*	foreach($nca as $value):
			echo "<br/>";
			echo "<br/>";
			echo "<br/>";
			//print_r($value->roles->toArray());
			$roles = $value->roles->toArray();
			//print_r($roles);
			foreach($roles as $role):
				//if($role['role_id'] == 2)
				echo $role['rolename']."--".$role['role_id'];
			endforeach;
			echo "<br/>";
			//echo $value['rbac'];
			echo "<br/>";
			//echo $value['namespace'];
		endforeach;
		*/
		//echo Q::ini('app_config/APP_DIR');
	}

    /* ******************************************************************** */
    function actionMakeAclFile()
    {
        $show_box['title'] = '生成ACL文件';

        //指定管理员角色或者最高权限角色
        $root_role = Q::ini('appini/sp_role/ADMIN');

        //取得数据表中的所有权限节点的数据
        //这种方法不能取得相关的用户角色的数据，直接生成数组  $nca = Admin_Permissions::find()->asArray()->getAll();
        $nca = Admin_Permissions::find()->getAll();

        // 将取得的数据数组进行重新构建        // ACL_NULL ACL_EVERYONE ACL_HAS_ROLE ACL_NO_ROLE
        $acl_arr = array();
        //默认命名空间允许管理员访问，注意要小写
        $acl_arr['all_controllers']['allow'] = '"'.$root_role.'"';
        foreach ( $nca as $value){
            $roles_arr = $value->roles->toArray();
			//如果是默认的命名空间，允许管理员访问
			//不是默认的命名空间必须以控制器名为关键字索引
            if ( $value['namespace'] != 'default'){
                $acl_arr[$value['namespace']]['all_controllers']['allow'] = '"'.$root_role.'"';
            }
            if ($value['rbac'] != 'ACL_NULL' && $value['rbac'] != 'ACL_HAS_ROLE'){
                if ( $value['namespace']=='default'){
                    $acl_arr[$value['controller']]['actions'][$value['action']]['allow'] = $value['rbac'];
                }else{
                    $acl_arr[$value['namespace']][$value['controller']]['actions'][$value['action']]['allow'] = $value['rbac'];
                }
            }elseif(!empty($roles_arr)){
                $roles = array();
                foreach( $roles_arr as $value2 )
                {
                    if ( $value2['rolename'] != $root_role ){
                        $roles[] = $value2['rolename'];
                    }
                }
                $roles = implode(',', Q::normalize($roles));
                if ( $value['namespace']=='default'){
                    $acl_arr[$value['controller']]['actions']['all_actions']['allow'] = '"'.$root_role.'"' ;
                    $acl_arr[$value['controller']]['actions'][$value['action']]['allow'] = '"'.$root_role.','.$roles.'"' ;
                }else{
                    $acl_arr[$value['namespace']][$value['controller']]['actions']['all_actions']['allow'] = '"'.$root_role.'"' ;
                    $acl_arr[$value['namespace']][$value['controller']]['actions'][$value['action']]['allow'] = '"'.$root_role.','.$roles.'"' ;
                }
            }
        }

        // 将数组转换成YAML格式，自定义了一个yamldump的方法
        $Helper_Spyc = new Helper_Spyc;
        $acl_yaml = "# <?php die(); ?>\n\n".$Helper_Spyc->YAMLDump($acl_arr);
        //框架生成的方法，不过不能声场YAML格式，而是jeson格式
        //$acl_yaml2 = Helper_YAML::dump($acl_arr);

        //取得acl文件物理路径
        $acl_filename = rtrim(dirname(__FILE__), '/\\') . DS .'..' . DS .'..' . DS .'..' . DS . 'config' . DS . 'acl.yaml';
        //写入方式打开写入文件的路径 
        $fp = fopen($acl_filename,"w+");
        //判断是否生成了文件，并返回结果
        if (fwrite($fp,$acl_yaml)){
                fclose($fp);
                return $this->_redirectMessage(
                    ' ACL 文件更新成功',
                    ' ACL 权限文件更新成功。',
                    url( 'admin::permissions/list' ));
            } else {
                fclose ($fp);
                return $this->_redirectMessage(
                    ' ACL 文件更新失败', 
                    ' ACL 权限文件更新失败，请联系管理员。',
                    url('admin::permissions/list'));
            }
    }
    
}


